home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
metkit
/
catfish.cpp
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-07
|
43KB
|
1,418 lines
// Copyright (C) 1996, 1997 Meta Four Software. All rights reserved.
//
// Main CatFish application sample code
//
//! rev="$Id: catfish.cpp,v 1.5 1997/05/27 00:06:05 jcw Rel $"
#include "stdafx.h"
#include "catfish.h"
#include "setupdlg.h"
#include <dos.h> // _dos_findfirst in GetCatalogDate
#ifdef _DEBUG
#undef THIS_FILE
static char BASED_CODE THIS_FILE[] = __FILE__;
#endif
#pragma warning(disable: 4702) // MSVC 1.52 gets confused: unreachable code
/////////////////////////////////////////////////////////////////////////////
// MSDN Q100770: Using Accelerator Keys When Modal Dialog Box Main Window
HWND ghDlg; // Handle to main dialog box
HACCEL ghAccelTable; // Handle to accelerator table
CTheApp ThisApp;
/////////////////////////////////////////////////////////////////////////////
// Use a simple version of localized date, time, and number formating.
static CString sShortDate = "MM/dd/yy"; // "d.M.yyyy", etc
static bool iTime = false; // true if 24h format
static bool iTLZero = true; // true if hour has 2 digits
static char sThousand = ','; // thousands separator
static char sTime = ':'; // time separator
static void SetInternationalSettings()
{
iTime = GetProfileInt("intl", "iTime", 0) != 0;
iTLZero = GetProfileInt("intl", "iTLZero", 1) != 0;
char buf [30];
if (GetProfileString("intl", "sShortDate", "MM/dd/yy", buf, sizeof buf))
sShortDate = buf;
if (GetProfileString("intl", "sThousand", ",", buf, sizeof buf))
sThousand = *buf;
if (GetProfileString("intl", "sTime", ":", buf, sizeof buf))
sTime = *buf;
}
/////////////////////////////////////////////////////////////////////////////
// Convert a number to comma-separated format, grouped in units of three.
// Optionally prefix with spaces (assuming two spaces is width of one digit).
// Finally, the zero value can be changed to a '-' upon request.
//
// Note: In many places, the code is simplified by the assumption that
// every digit has exactly the same width as two space characters.
// This works for the selected font (MS Sans Serif, font size 8).
// It allows us to present a nice columnar interface without having
// to figure out each of the string position in pixels. There are
// several more assumptions like this (e.g. "k " is like "Mb").
static CString CommaNum(DWORD num, int groups =0, BOOL zero =TRUE)
{
CString s;
s.Format("%lu", num);
int g = 0;
int n = s.GetLength();
while (n > 3)
{
n -= 3;
s = s.Left(n) + sThousand + s.Mid(n);
++g;
}
if (--groups >= 0)
{
int w = ((3 - n) % 3) * 2;
if (g < groups)
w += 7 * (groups - g);
s = CString (' ', w) + s;
}
if (!zero && (s == "0" || s.Right(2) == " 0"))
s = s.Left(s.GetLength() - 1) + " -";
return s;
}
/////////////////////////////////////////////////////////////////////////////
// Convert a DOS date and TIME words to short format strings.
// Lets be nice to a lot of people and adopt their local conventions.
static CString ShortDate(WORD date)
{
if (date == 0)
return ""; // will be ok as long as the date is last item
int w = 0;
char buf [10];
char* q = buf;
// decode the short date, deal with 1- and 2-digit fields
const char* p = sShortDate;
while (*p)
{
int i;
switch (*p++)
{
default: *q++ = *(p-1);
continue;
case 'd': i = date & 0x1F;
break;
case 'M': i = (date >> 5) & 0x0F;
break;
case 'y': i = ((date >> 9) + 80) % 100;
break; // 4-digit years are treated as 2-digit
}
if (i < 10 && *p != *(p-1))
++w;
else
*q++ = (char) (i / 10 + '0');
*q++ = (char) (i % 10 + '0');
while (*p == *(p-1))
++p;
}
// centering is easy, since one digit is as wide as two spaces
CString t (' ', 2 * w);
// alignment depends on whether the year is first or last
if (sShortDate[0] == 'y')
return CString (buf, q - buf) + t;
return t + CString (buf, q - buf);
}
static CString ShortTime(WORD time)
{
int h = time >> 11;
int m = (time >> 5) & 0x3F;
char ampm = "ap" [h / 12];
if (!iTime)
h = (h + 11) % 12 + 1; // dec, then inc, so 0 becomes 12
CString s;
s.Format("%02d%c%02d", h, sTime, m);
if (!iTime)
s += ampm;
if (!iTLZero && s[0] == '0')
s = " " + s.Mid(1); // replace leading zero with two spaces
return s;
}
/////////////////////////////////////////////////////////////////////////////
// Make a string fit in the specified number of pixels on given device.
// Characters at the end are replaced by an ellipsis to make the string fit.
// There is some trickery in here to optimize this very common calculation.
static BOOL FitString(CDC* dc, CString& text, int width)
{
CSize sz = dc->GetTextExtent(text, text.GetLength());
if (sz.cx <= width)
return TRUE; // make the most common case fast
// Assumption: "...xyz" is just as wide as "xyz..."
CString s = "..." + text;
int n = s.GetLength();
while (--n > 3)
{
sz = dc->GetTextExtent(text, n);
if (sz.cx <= width)
break;
}
text = text.Left(n - 3) + "...";
return FALSE;
}
/////////////////////////////////////////////////////////////////////////////
// Disables redraw and clears listbox, will reset normal state in destructor
class ListBoxFreezer
{
public:
ListBoxFreezer (CListBox& lb)
: list (lb)
{
list.SetRedraw(FALSE);
list.ResetContent();
}
~ListBoxFreezer ()
{
list.SetRedraw(TRUE);
list.Invalidate();
}
private:
CListBox& list;
};
/////////////////////////////////////////////////////////////////////////////
// Return file date in display format, or an empty string if file not present
CString GetCatalogDate(CString& catName)
{
CString s = catName;
s += FILE_TYPE;
#ifndef _WIN32
_find_t fbuf;
if (_dos_findfirst(s, _A_NORMAL, &fbuf) != 0)
return "";
// pick up the name as it is stored on disk (properly capitalized)
s = fbuf.name;
ASSERT(s.Right(4).CompareNoCase(FILE_TYPE) == 0);
catName = s.Left(s.GetLength() - 4);
return ShortDate((WORD) fbuf.wr_date) + " "
+ ShortTime((WORD) fbuf.wr_time);
#endif
return "?";
}
/////////////////////////////////////////////////////////////////////////////
// The one and only application object
CTheApp::CTheApp ()
: CWinApp ("CatFish")
{
}
BOOL CTheApp::InitInstance()
{
SetDialogBkColor();
SetInternationalSettings();
ghAccelTable = LoadAccelerators(